package com.talent.web.pay;

import cn.hutool.core.util.ObjectUtil;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.talent.web.config.alipay.AliPayProperties;
import com.talent.web.enums.OrderStatus;
import com.talent.web.enums.PayType;
import com.talent.web.enums.ResponseEnum;
import com.talent.web.exception.TalentException;
import com.talent.web.model.entity.TlOrder;
import com.talent.web.service.ITlOrderService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author: hszhou
 * @Date: 2025/3/26 14:05
 * @Description: 支付宝相关接口
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class AlipayService {


    private final AlipayClient alipayClient;

    private final ITlOrderService orderService;

    private final AliPayProperties aliPayProperties;

    private final static String TRADE_SUCCESS = "TRADE_SUCCESS";

    private final static String TRADE_FINISHED = "TRADE_FINISHED";


    /**
     *
     * @param orderId 订单ID
     * @return app支付的页面信息
     */
    public String appPay(Long orderId) {

        AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
        model.setBody("我是测试数据");
        TlOrder order = orderService.getById(orderId);
        if(ObjectUtil.isEmpty(order)){
            throw new TalentException(ResponseEnum.ORDER_NOT_EXIT);
        }
        //订单标题
        model.setSubject("测试");
        // outTradeNo 订单号  商户自己的订单号 由商家自定义 64个字符以内 仅支持字母 数字 下划线且需保证在商户端不重复
        model.setOutTradeNo(order.getOutTradeNo());
        model.setTimeoutExpress("30m");
        //totalAmount 订单总金额 单价为元
        model.setTotalAmount(order.getPrice().toString());
        request.setBizModel(model);
        String notifyUrl = aliPayProperties.getNotifyUrl();
        log.info("回调地址【{}】",notifyUrl);
        request.setNotifyUrl(aliPayProperties.getNotifyUrl());
        try {
            //这里和普通的接口调用不同，使用的是sdkExecute
            AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
          //  System.out.println(response.getBody());//就是orderString 可以直接给客户端请求，无需再做处理。
            return response.getBody();
        } catch (AlipayApiException e) {
            log.error("支付宝下单接口失败【{}】",e.getErrMsg());
            e.printStackTrace();
        }

        return null;
    }


    public void callback(HttpServletRequest request){
        try{
            Map<String, String> params = parseRequest(request);

            //进行验签
            String alipayPublicKey = aliPayProperties.getAlipayPublicKey();
            String charset = aliPayProperties.getCharset();
            String signType = aliPayProperties.getSignType();
            boolean flag = AlipaySignature.rsaCheckV1 (params,alipayPublicKey, charset,signType);
            log.info("验签结果【{}】",flag);
            if(flag){
                // 商户订单号
                String outTradeNo = params.get("out_trade_no");
                // 支付宝交易号
                String tradeNo = params.get("trade_no");
                // 交易状态
                String tradeStatus = params.get("trade_status");
                log.info("商户订单号【{}】,支付宝交易号【{}】,交易状态【{}】",outTradeNo,tradeNo,tradeStatus);
                if (TRADE_SUCCESS.equals(tradeStatus) ||TRADE_FINISHED.equals(tradeStatus)) {
                    // 更新订单状态为已支付
                    // updateOrderStatus(outTradeNo, tradeNo, "已支付");
                    orderService.updateOrder(outTradeNo,tradeNo, OrderStatus.PAID, PayType.ALIPAY);
                }

            }else{
                log.error("支付宝回调验签失败");
            }
        }catch (AlipayApiException ex){
            log.error("支付宝回调参数失败【{}】",ex.getErrMsg());

        }


    }


    /**
     * 从请求中拿到数据
     * @param request 请求对象
     * @return 参数对象
     */
    private Map<String,String> parseRequest(HttpServletRequest request){
        Map<String,String> params = new HashMap<> (16);
        Map<String, String[]> requestParams = request.getParameterMap();
        for (String name : requestParams.keySet()) {
            String[] values = requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }
            //乱码解决，这段代码在出现乱码时使用。
            //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }
        return params;
    }
}
